package org.pentaho.di.ui.spoon.navigation.design.classification;

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.eclipse.jface.window.DefaultToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.LaniusClassExpandBar;
import org.eclipse.swt.widgets.LaniusClassExpandItem;
import org.eclipse.swt.widgets.LaniusClassTree;
import org.eclipse.swt.widgets.ExpandBar;
import org.eclipse.swt.widgets.Tree;
import org.yzbdl.lanius.core.plugins.metastore.LdrClassificationEntity;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.ui.spoon.Spoon;
import org.pentaho.di.ui.spoon.navigation.Bundle;
import org.pentaho.di.ui.spoon.navigation.design.classification.category.Category;
import org.pentaho.di.ui.spoon.navigation.design.classification.plugin.Plugin;

/**
 * 分类，例如自定义的分类、常用、云端、本地
 *
 * @author hs@yzbdl.ac.cn
 */
public class Classification extends Bundle {
    private static Class<?> PKG = Spoon.class;
    public static final String COMMONLY_NAME = BaseMessages.getString(PKG, "Classification.Name.Commonly");
    public static final String DEFAULT_NAME = BaseMessages.getString(PKG, "Classification.Name.Default");
    public static final String MARKET_NAME = BaseMessages.getString(PKG, "Classification.Name.Market");
    public static final Integer COMMONLY_SORT = 1;
    public static final Integer DEFAULT_SORT = 9998;
    public static final Integer MARKET_SORT = 9999;

    //******* data******

    private LdrClassificationEntity ldrClassificationEntity;

    private Set<Plugin> plugins = new LinkedHashSet<>();

    private Map<Integer, Plugin> pluginsMap = new LinkedHashMap<>();

    private Set<Category> categories = new LinkedHashSet<>();

    private Map<Integer, Category> categoriesMap = new LinkedHashMap<>();

    //******* view *****

    /**
     * tree
     */
    private LaniusClassTree tree;

    private LaniusClassExpandItem expandItem;

    public Classification() {
        super(null);
    }

    public Classification(Spoon spoon, DefaultToolTip toolTip, LaniusClassExpandBar expandBar, LdrClassificationEntity ldrClassificationEntity){
        super(spoon);
        this.ldrClassificationEntity = ldrClassificationEntity;
        this.tree = generateTree(toolTip, expandBar);
    }

    public boolean isEmpty() {
        return this.plugins.isEmpty() && this.categories.isEmpty();
    }

    public void dispose() {
        this.tree.dispose();
        this.expandItem.dispose();
    }

    private LaniusClassTree generateTree(DefaultToolTip toolTip, LaniusClassExpandBar expandBar) {
        tree = new LaniusClassTree(expandBar, SWT.NONE, getSpoon(), toolTip, this.ldrClassificationEntity);
        tree.setLayout(new FillLayout());

        this.getSpoon().props.setLook(tree);

        setTreeListener(toolTip, expandBar);

        expandItem = new LaniusClassExpandItem(expandBar, SWT.NONE);
        expandItem.setExpanded(isExpanded(getClassificationEntity().getExpanded()));
        expandItem.setText(getClassificationEntity().getName());
        expandItem.setControl(tree);
        expandItem.setHeight(expandBar.getBounds().height);
        expandItem.setClassificationEntity(getClassificationEntity());
        return tree;
    }


    private void setTreeListener(DefaultToolTip toolTip, ExpandBar expandBar){
//        addSelectionListener();
//        addTreeListener();
//        addMouseMoveListener(toolTip, expandBar);
//
//        addMouseListener();
//        addMenuDetectListener();
//
//        addDefaultKeyListeners();
        addDragSourceToTree(tree);
    }

    //	private TreeSelection[] getTreeObjects(final Tree tree) {
    //		return this.getSpoon().delegates.tree.getTreeObjects(tree, null, tree);
    //	}

    private void addDragSourceToTree(final Tree tree) {
        this.getSpoon().delegates.tree.addDragSourceToTree(tree, null, tree);
    }

    public LdrClassificationEntity getClassificationEntity() {
        return ldrClassificationEntity;
    }

    public void setClassificationEntity(LdrClassificationEntity ldrClassificationEntity) {
        this.ldrClassificationEntity = ldrClassificationEntity;
    }

    public void addPlugin(Plugin plugin) {
        this.plugins.add(plugin);
        this.pluginsMap.put(plugin.getId(), plugin);
    }

//    public void removePlugin(String pluginId) {
//        Plugin plugin = this.pluginsMap.get(pluginId);
//        this.plugins.remove(plugin);
//        this.pluginsMap.remove(pluginId);
//    }

    public Set<Plugin> getPlugins() {
        return new LinkedHashSet<>(plugins);
    }

    public void setPlugins(Set<Plugin> plugins) {
        this.plugins = plugins;
        for (Plugin plugin : plugins) {
            this.pluginsMap.put(plugin.getId(), plugin);
        }
    }

    public Set<Category> getCategories() {
        return categories;
    }

    public void setCategories(Set<Category> categories) {
        this.categories = categories;

        for (Category category : categories) {
            this.categoriesMap.put(category.getCategoryEntity().getId(), category);
        }
    }

    public Map<Integer, Category> getCategoriesMap() {
        return categoriesMap;
    }

    public LaniusClassTree getTree() {
        return tree;
    }

    public void setTree(LaniusClassTree tree) {
        this.tree = tree;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o){
            return true;
        }
        if (o == null || getClass() != o.getClass()){
            return false;
        }
        Classification that = (Classification) o;
        return Objects.equals(ldrClassificationEntity, that.ldrClassificationEntity);
    }

    @Override
    public int hashCode() {
        return Objects.hash(ldrClassificationEntity);
    }
}
